package stack.stackDefine;

/**
 * 数组实现栈
 */

import java.util.Arrays;

public class MyArrayListStack<T> implements StackService<T> {
    private int DEFAULT_SIZE=16;  //定义栈的初始默认长度
    private int capacity;   // 保存栈的长度
    private int size;   //元素个数
    private Object[] elementData;  //保存栈中的元素

    public int getCapacity() {
        return capacity;
    }
    public void outPutReverse(){
        for (int i = 0; i < size; i++) {
            System.out.print(elementData(i));
        }
    }

    public void setCapacity(int capacity) {
        this.capacity = capacity;
    }

    public MyArrayListStack() {
        capacity = DEFAULT_SIZE;
        elementData = new Object[capacity];
        size = 0;
    }
    // 以指定长度的大小来创建栈
    public MyArrayListStack(int initSize) {
        capacity = 1;
        while (capacity<initSize)
            capacity <<=1;  //将capacity设置成大于initSize的最小2次方
        elementData = new Object[capacity];
    }

    @Override
    public int getLength() {
        return this.size;
    }

    public T getAt(int idx){
        return elementData(idx);
    }
    @Override
    public T pop() {
        if (empty()){
            throw new IndexOutOfBoundsException("栈空，不能出栈");
        }
        T oldValue =elementData(size-1);
        elementData[--size] = null; ////让垃圾回收器及时回收，避免内存泄露
        return oldValue;
    }

    /**
     *  返回运算符的优先级，数字越大优先级就越高
     *  目前 表达式只有+ - * /
     */
    public int priority(int oper){
        if (oper == '*' || oper =='/'){
            return 1;
        }else if(oper =='+' || oper =='-'){
            return 0;
        }else
            return -1;
    }
    public boolean isOper(char val){
        return val == '+' || val =='-' || val=='*' ||val =='/' ;
    }
    public int cal(int num1,int num2,char oper){
        int res = 0;
        switch (oper){
            case '+':
                res = num1+num2;
                break;
            case '-':
                res = num2-num1;
                break;
            case '*':
                res = num1*num2;
                break;
            case '/':
                res = num2/num1;
                break;
            default:
                break;
        }
        return res;
    }

    /**
     * 我用得有一点鸡肋了 ，但ArrayList中有这么用过
     */
    T elementData(int index){
        return (T) elementData[index];
    }

    /**
     *     动态扩容 真的太牛逼了！
      */
    public void ensureCapacity(int minCapacity){
        if (minCapacity>capacity){
            while(capacity<minCapacity)
                capacity <<=1;
        }
        elementData = Arrays.copyOf(elementData,capacity);
    }
    @Override
    public void push(T t) {
        ensureCapacity(size+1);
        elementData[size++] = t;
    }

    @Override
    public T peek() {
        if (size==0){
            throw new ArrayIndexOutOfBoundsException("size = 0");
        }
        return elementData(size-1);
    }

    @Override
    public boolean empty() {
        return size==0;
    }
    public boolean isNotEmpty(){
        return !empty();
    }
    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            elementData[i] = null;
        }
        size = 0;
    }
    public void display() {
        if (size==0){
            System.out.println("[]");
        }
        StringBuilder sb = new StringBuilder("");
        for (int j =size-1;j>=0;j--){
            sb.append(elementData[j].toString()+", ");
        }
        int len = sb.length();
        System.out.println(sb.delete(len - 2, len).append(']').toString());
    }
    public void conversion10_n(int num,int toNum){
        MyArrayListStack<Integer> stack = new MyArrayListStack<>();
        while (num!=0){
            stack.push(num%toNum);
            num = num/8;
        }
        while (stack.isNotEmpty()){
            System.out.printf("%d",stack.pop());
        }
    }
}
